package com.cloud.xtools.user.service.admin.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloud.xtools.common.exception.ServiceException;
import com.cloud.xtools.common.redis.RedisService;
import com.cloud.xtools.user.domain.entity.Permission;
import com.cloud.xtools.user.domain.entity.RolePermission;
import com.cloud.xtools.user.mapper.RolePermissionMapper;
import com.cloud.xtools.user.service.admin.PermissionService;
import com.cloud.xtools.user.service.admin.RolePermissionService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author Daixinguo
 */
@Service
@RequiredArgsConstructor
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission> implements RolePermissionService {

    @Autowired
    private RedisService redisService;

    @Override
    // 开启事务
    @Transactional
    public void assignPermissions(Long roleId, List<Long> permissionIds, List<String> permissionIdentities) {
        // 删除该角色之前所有权限
        removeByMap(Map.of("role_id", roleId));

        // 批量保存数据到 role_permissions 表中
        List<RolePermission> rolePermissions = permissionIds.stream()
                .map(permissionId -> {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setRoleId(roleId);
                    rolePermission.setPermissionId(permissionId);
                    rolePermission.setCreatedAt(LocalDateTime.now());
                    rolePermission.setUpdatedAt(LocalDateTime.now());
                    return rolePermission;
                })
                .toList();

        saveBatch(rolePermissions);

        // 将角色的权限保存到 redis 中，保存为 set （保证不重复，后期可以方便的取出多个角色对应权限的并集）
        String key = "role_permission:" + roleId;
        redisService.delete(key);
        // 将权限的 identity 保存到 redis 中，在验证权限时需要通过 identity 来做验证
        permissionIdentities.forEach(permissionIdentity -> redisService.addToSet(key, permissionIdentity));
    }

    @Override
    public void destroyByRoleId(Long roleId) {
        removeByMap(Map.of("role_id", roleId));
    }

    @Override
    public void destroyByPermissionId(Long permissionId) {
        removeByMap(Map.of("permission_id", permissionId));
    }
}
